package com.yunhai.device.mqtt;

import com.alibaba.fastjson.JSONObject;
import com.yunhai.common.dto.Ret;
import com.yunhai.device.service.*;
import com.yunhai.model.entity.dms.DmsDeviceInfoEntity;
import com.yunhai.model.entity.dms.DmsPullTeaNetsignEntity;
import com.yunhai.model.entity.sys.SysVersionPartEntity;
import com.yunhai.model.vo.dms.DmsPullTeaAlarmVo;
import com.yunhai.model.vo.dms.DmsPullTeaDataVo;
import com.yunhai.model.vo.dms.DmsPullTeaNetsignVo;
import com.yunhai.model.vo.sys.SysVersionTotal;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.concurrent.*;

@Service
public class MqttMsgHandle {

    @Resource
    private SysVersionPartService sysVersionPartService;
    @Resource
    private DmsPullTeaAlarmService pullTeaAlarmService;
    @Resource
    private DmsPullTeaDataService pullTeaDataService;
    @Resource
    private PullTeaNetsignService pullTeaNetsignService;
    @Resource
    private DeviceInfoService deviceInfoService;



    private ThreadPoolExecutor executor = new ThreadPoolExecutor(
            2, // corePoolSize
            50, // maximumPoolSize
            60L, // keepAliveTime
            TimeUnit.SECONDS,
            new LinkedBlockingQueue<>(100), // 任务队列容量100
            Executors.defaultThreadFactory(),
            new ThreadPoolExecutor.AbortPolicy() // 拒绝策略
    );


    public void handlePkgUpdate(MqttClient mqttClient, TopicEntity topicEntity, String fwVer ) throws Exception {
        final MqttMsgHandle  self = this;
        executor.execute(() -> {
            String lastVersion = null;
            try {
                lastVersion = sysVersionPartService.getLastVersionOfDeviceType(topicEntity.getDeviceType(), fwVer);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
            SysVersionTotal versionTotal;
            //不需要更新返回的数据类型
            if( lastVersion == null ){
                versionTotal  = new SysVersionTotal();
                versionTotal.setFwSize(0L);
                versionTotal.setFwPkgAmount(0);
            }
            else {
                //需要更新返回的数据类型
                try {
                    versionTotal = sysVersionPartService.getVersionFileTotalData(topicEntity.getDeviceType(),lastVersion);
                    self.publishContent( mqttClient, topicEntity , versionTotal );
                } catch (Exception e) {
                    System.out.println("update_pkg 获取数据异常~~~~");
                    e.printStackTrace();
                    self.publishContent( mqttClient, topicEntity , Ret.fail() );
                }
            }

        });
    }


    public void handlePkgItemUpdate( MqttClient mqttClient, TopicEntity topicEntity, String fwVer, String index ) throws Exception {
        if( fwVer == null ){
            return;
        }

        final MqttMsgHandle  self = this;
        executor.execute(() -> {
            SysVersionPartEntity versionFilePartData = null;
            try {
                versionFilePartData = sysVersionPartService.getVersionFilePartData(topicEntity.getDeviceType(), fwVer, Integer.valueOf(index));
                self.publishContent( mqttClient, topicEntity , versionFilePartData );
            } catch (Exception e) {
                System.out.println("update_pkg 获取数据异常~~~~");
                e.printStackTrace();
                self.publishContent( mqttClient, topicEntity , Ret.fail() );
            }

        });

    }

    /**
     * 处理设备上传的数据
     * */
    public void handleDeviceUpdateState( TopicEntity topicEntity,
                                         JSONObject jsonObject ) throws Exception {

        final MqttMsgHandle  self = this;
        executor.execute(() -> {
            try {

                //设备的 imei
                String imei = topicEntity.getDeviceId();
                //获取 type
                Integer type = jsonObject.getInteger("type");
                //获取 status
                Integer status = jsonObject.getInteger("status");
                //数量
                Integer count = jsonObject.getInteger("count");

//                DmsDeviceInfoEntity deviceInfo = deviceInfoService.getDeviceInfoDetailByImei(imei);
//                Long storeId = deviceInfo.getStoreId();
                DmsPullTeaDataVo pullTeaDataVo = new DmsPullTeaDataVo();
//                pullTeaDataVo.setStoreId(storeId);
//                pullTeaDataVo.setStoreName(deviceInfo.getStoreName());
                pullTeaDataVo.setImei(imei);
                pullTeaDataVo.setCount(count);
                pullTeaDataVo.setStatus(status);
                pullTeaDataVo.setType(type);
//                pullTeaDataVo.setDeviceId(deviceInfo.getId());

                pullTeaDataService.addDmsPullTeaData(pullTeaDataVo);

            } catch (Exception e) {
                System.out.println("upload_status 获取数据异常~~~~");
                e.printStackTrace();
            }

        });

    }

    /**
     * 上传设备的告警
     * */
    public void handleDeviceUpdateAlarm( TopicEntity topicEntity,
                                         JSONObject jsonObject ) throws Exception {

        final MqttMsgHandle  self = this;
        executor.execute(() -> {
            try {

                //设备的 imei
                String imei = topicEntity.getDeviceId();
                //获取 type
                Integer type = jsonObject.getInteger("type");
                //获取 status
                Integer status = jsonObject.getInteger("status");
//                DmsDeviceInfoEntity deviceInfo = deviceInfoService.getDeviceInfoDetailByImei(imei);
//                Long storeId = deviceInfo.getStoreId();
                DmsPullTeaAlarmVo pullTeaAlarmVo = new DmsPullTeaAlarmVo();
//                pullTeaAlarmVo.setStoreId(storeId);
//                pullTeaAlarmVo.setStoreName(deviceInfo.getStoreName());
                pullTeaAlarmVo.setImei(imei);
                pullTeaAlarmVo.setStatus(status);
                pullTeaAlarmVo.setType(type);
//                pullTeaAlarmVo.setDeviceId(deviceInfo.getId());
                pullTeaAlarmService.addDmsPullTeaAlarm(pullTeaAlarmVo);

            } catch (Exception e) {
                System.out.println("upload_info 获取数据异常~~~~");
                e.printStackTrace();
            }

        });
    }


    public void handlePullTeaDeviceUploadNetSign(TopicEntity topicEntity, JSONObject jsonObject) {
        final MqttMsgHandle  self = this;
        executor.execute(() -> {
            try {

                //设备的 imei
                String imei = topicEntity.getDeviceId();
                //获取 type
                Integer value = jsonObject.getInteger("value");
//                DmsDeviceInfoEntity deviceInfo = deviceInfoService.getDeviceInfoDetailByImei(imei);
//                Long storeId = deviceInfo.getStoreId();
                DmsPullTeaNetsignVo netsignVo = new DmsPullTeaNetsignVo();
//                netsignVo.setDeviceId(deviceInfo.getId());
                netsignVo.setImei( imei );
                netsignVo.setValue(value);
//                netsignVo.setStoreId(deviceInfo.getStoreId());
//                netsignVo.setStoreName(deviceInfo.getStoreName());

                pullTeaNetsignService.addPullTeaNetsign(netsignVo);

            } catch (Exception e) {
                System.out.println("upload_info 获取数据异常~~~~");
                e.printStackTrace();
            }

        });
    }


    public void publishContent( MqttClient mqttClient, TopicEntity topicEntity,  Object obj ) {
        String msgStr = JSONObject.toJSONString(obj);
        MqttMessage sendMessage = new MqttMessage(msgStr.getBytes(StandardCharsets.UTF_8));
        sendMessage.setQos(topicEntity.getQos());

        System.out.println("发送主题: "+(topicEntity.getSendTopic()));
        try {
            mqttClient.publish(topicEntity.getSendTopic(), sendMessage);
        } catch (MqttException e) {
            throw new RuntimeException(e);
        }
    }

}
